#coding:utf-8

'''
	* Author： Lingo
	* E-mail: 15klli@stu.edu.cn
	* Version: 1.0
	* Description: 主要功能为：一键导出指定下属组织的信息为csv,包括 [序号,userId,姓名,登录账号,性别,手机号码,是否面验,服务时数,培训时数,归属组织]等
	* Function list: 
		login: 实现登录，以便让服务器创建session
		getDetails: 通过userId 获取这个用户的详细信息，通过解析页面获取信息，并返回指定信息		
		getMemeberInfo： 通过districtId 来获取用户的基本信息（userId），并调用getDetails
		getSubOrg(): 获取直属下属组织的districtId，并调用getMemeberInfo
		writeInFile: 将 records 写入csv文件
	* Others： linux系统下由于编码问题可能会出现错误
'''

import requests
import random
import hashlib
import json
import xlwt
import csv
import codecs
import sys
from bs4 import BeautifulSoup

session=requests.Session()

def login():
	global session
	headers={
	'Host':'www.izyz.org',
	'Referer':'https://www.izyz.org/index',
	'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.62 Safari/537.36',
	'X-Requested-With':'XMLHttpRequest'
	}
	imgUrl='https://www.izyz.org/api/common/randomcode/staticimge4login.do?rc='+str(random.random())
	md5=hashlib.md5()
	rs=session.get(imgUrl,headers=headers)
	with open('vcode.png','wb') as f:
		f.write(rs.content)
	code=str(raw_input(u'please input the vcode(验证码): '))
	account=str(raw_input(u'please input the account(账号): '))
	paw=str(raw_input(u'please input the password(密码): '))
	md5.update(paw)	
	password=md5.hexdigest()
	loginUrl='https://www.izyz.org/api/login/userPcLogin.do?xc=0.908717681209304'
	data={
		'loginType':2,
		'userName':'stu-lic',
		'password':password,
		'captchaCode':code,
	}
	rs=session.post(loginUrl,data=data,headers=headers)
	# todo: handle login failed.
def getDetails(userId):
	record={}
	detailUrl='https://www.izyz.org/manager/volunteer/viewUser?userId=%s&viewType=ref'%userId
	rs=session.get(detailUrl)
	# todo: failed situation
	soup=BeautifulSoup(rs.content,'html.parser')
	info=soup.find_all('td')
	record['servicesTime']=info[3].text.split('\t')[3].strip()
	record['trainTime']=info[4].text.split('\t')[3].strip()
	#record['politicalStatus']=info[10].text.split('\t')[9].strip()  #need to fix
	org=soup.find_all('td')[21].find_all('td')
	organization=''
	for i in xrange(0,len(org)):
		organization+=org[i].text.strip()
		if i!=(len(org)-1):
			organization+='\n'
	record['organization']=organization
	return record
def getMemeberInfo(districtId=''):
	global session	
	records=[]
	listUrl='https://www.izyz.org/api/manager/volunteer/searchUser.do?searchType=ref&zzName=&districtId=%s&subDistrict=true&isValidation=1000&userName=&loginName=&idcardCode=&mobile=&detectStatuses=&inspection=&beginDateInput=&endDateInput=&pageIndex=1&pageSize=500'%districtId
	rs=session.get(listUrl) 
	content = json.loads(rs.content)
	accRecords=content['records']
	page=int(content['totalPage'])
	maxi=200
	if page>1:
		for i in xrange(2,maxi+1):
			listUrl='https://www.izyz.org/api/manager/volunteer/searchUser.do?searchType=ref&zzName=&districtId=%s&subDistrict=true&isValidation=1000&userName=&loginName=&idcardCode=&mobile=&detectStatuses=&inspection=&beginDateInput=&endDateInput=&pageIndex=%d&pageSize=500'%(districtId,i)
			rs=session.get(listUrl)
			temp=json.loads(rs.content)['records']
			# print i
			if len(temp)==0:
				break
			accRecords+=temp
	for i in accRecords:
		record={}		
		record['userName']=i['userName']
		record['loginName']="'"+i['loginName']
		record['gender']=i['gender']
		record['phoneNumber']=i['mobile']
		record['isFaceValidate']=i['inspection']
		record['userId']=i['userId']
		record=dict(record,**getDetails(i['userId']))
		records.append(record)
	return records
def getSubOrg():
	global session
	# get the highest organizaiton info like id
	thisUrl='https://www.izyz.org/district/district/districtTree?districtId=&type=0&_=1544095645581'  #
	rs=session.get(thisUrl)
	soup=BeautifulSoup(rs.content,'html.parser')
	aimText=soup.find_all('script')[2].text
	left=aimText.find('{')
	right=aimText.find('}')
	info=json.loads(aimText[left:right+1])
	name=info['name']
	districtId=info['id']
	# get the organization trees' info
	url='https://www.izyz.org/district/district/getDistrictTreeDlg'
	data={
	'districtId':districtId
	}
	rs=session.post(url,data=data)
	treesInfo=json.loads(rs.content)
	for i in treesInfo:		
		districtId=i['id']
		name=i['name']
		print u'正在导出%s的成员信息...'%name
		records=getMemeberInfo(districtId)
		writeInFile(fileName=name,records=records)
def writeInFile(records,fileName=''):
	csvFile=f = codecs.open('%sMemeberInfo.csv'%fileName, 'wb')  
	csvFile.write(codecs.BOM_UTF8)
	outer = csv.writer(csvFile)
	reload(sys)
	sys.setdefaultencoding( "utf-8" )
	order=0	
	outer.writerow([u'序号','userId',u'姓名',u'登录账号',u'性别',u'手机号码',u'是否面验',u'服务时数',u'培训时数',u'归属组织'])
	contents=[]
	for i in records:
		content=[]
		order+=1
		content.append(order)
		content.append(i['userId'])
		content.append(i['userName'])
		if i['gender']==1:
			content.append(u'男')
		else:
			content.append(u'女')
		# content.append(i['politicalStatus'])
		content.append(i['loginName'])
		content.append(i['phoneNumber'])
		if int(i['isFaceValidate'])==1:			
			content.append(u'是')
		else:
			content.append(u'否')
		content.append(i['servicesTime'])
		content.append(i['trainTime'])
		content.append(i['organization'])	
		contents.append(content)
	outer.writerow(contents)
	csvFile.close()

login()
getSubOrg()
